#include <stdio.h>
#include "klist.h"

sj_void klist_init(struct klist *list)
{
	list->prev =list;
	list->next =list;
}

sj_void klist_node_init(struct klist_node *list,sj_void *node)
{
	list->prev=list;
	list->next=list;
	list->node=node;
}

sj_void klist_add_tail(struct klist_node *n,struct klist *k)
{
	struct klist_node *prev = k->prev;
	struct klist_node *next = prev->next;

    n->prev =prev;
    n->next =next;

    next->prev=n;
    prev->next=n;
}

sj_void klist_add_head(struct klist_node *n,struct klist *k)
{
	struct klist_node *next = k->next;
	struct klist_node *prev = next->prev;

    n->prev =prev;
    n->next =next;

    next->prev=n;
    prev->next=n;
}

sj_void* klist_node_get(struct klist_node *knode)
{
	return knode->node;
}

sj_void klist_iter_init(struct klist *k, struct klist_iter *iter)
{
	iter->i_klist=k;
	iter->i_cur=NULL;
}

struct klist_node *klist_next(struct klist_iter *iter)
{
	struct klist *list = iter->i_klist;
	struct klist_node *last = iter->i_cur;

	if(last)
	{
		iter->i_cur = last->next;
	}
	else 
	{
		iter->i_cur=list->next;
	}		

	return iter->i_cur;
}

struct klist_node *klist_prev(struct klist_iter *iter)
{
	struct klist *list = iter->i_klist;
	struct klist_node *last = iter->i_cur;
	
	if(last)
	{
		iter->i_cur = last->prev;
	}
	else 
	{
		iter->i_cur=list->prev;
	}		

	return iter->i_cur;
}
sj_void klist_iter_exit(struct klist_iter *iter)
{
	iter->i_cur=NULL;
}

sj_bool klist_iter_is_head(struct klist_iter *iter)
{
	if(iter->i_cur)
	{
		if(iter->i_cur == iter->i_klist)
		{
			return sj_true;
		}
	}
	return sj_false;
}
#if 0
int main(int argc, char const *argv[])
{
	typedef struct 
	{
		int index;
		char *name;
	}driver_data;

	static driver_data uart={97,"uart"};
	static driver_data iic={90,"iic"};
	static driver_data spi={91,"spi"};
	static driver_data can={92,"can"};

	static KLIST_INIT(driver_list);
	static KLIST_NODE_INIT(iic_driver,&iic);
	static KLIST_NODE_INIT(uart_driver,&uart);
	static KLIST_NODE_INIT(spi_driver,&spi);
	static KLIST_NODE_INIT(can_driver,&can);
	static KLIST_ITER_INIT(driver_list_iter,&driver_list);

	klist_add_tail(&iic_driver,&driver_list);
	klist_add_tail(&uart_driver,&driver_list);
	klist_add_tail(&spi_driver,&driver_list);
	klist_add_tail(&can_driver,&driver_list);




	struct klist_node *knode = klist_next(&driver_list_iter);
	while(!klist_iter_is_head(&driver_list_iter))
	{
		driver_data *data = (struct driver_data *)klist_node_get(knode);
		printf("%s\n",data->name);
		knode=klist_next(&driver_list_iter);
	}

	return 0;
}
#endif
